/**
 * Copyright  2025, Hai Yue Xing He Technology Co., Ltd
 * 
 * @author        ZHAO LIMIN
 * @version       1.0.1
 * @since         2025-04
 * HYXHPolyline.ts      标准类，用于记录矢量图：多段线
 *                      将cc.object 进行矢量化用于检测碰撞，相叠等。
 */
import { HGeometry, ILineIndex } from "./HYXHGeometry";
import { HYXHGeoTools} from "./HYXHGeoTools";
import { PointsCollection } from "./HYXHPointsCollection";
import { ICartesian } from "./Cartesian";
import { UNION_NUMBER_ARRAY } from "./HDataType";
import { Cartesian3 } from "./Cartesian3";
import { Check } from "./Check";
import { defined } from "./Defined";
/**
 * 矢量图-多段线，由多个线段组成的曲线。
 */
export class HPolyline implements HGeometry {
    /**
     * path是一个封闭的Path，即起始点和终止点有相同的坐标值。Ring有内部和外部属性‌
     * 用来描述多段
     */
    public paths: Map<number, PointsCollection>;
    constructor() {
        this.paths = new Map<number, PointsCollection>();
    }    

    pack(layer: number, array: UNION_NUMBER_ARRAY, startIndex: number): UNION_NUMBER_ARRAY {
        Check.defined('array', array)
        if (!defined(array)) {
            array = new Array<number>(); 
        }
        if (startIndex < 0) {
            startIndex = 0; 
        }
        if ( this.paths.size == 0) {
            return array;
        }
        if (this.paths.has(layer) === false) {
            return array;
        }

        let path = this.paths.get(layer);
        path.pack(array, startIndex);
        return array;
    }
    unpack(layer: number, array: UNION_NUMBER_ARRAY, startIndex: number) {
        Check.defined('array', array);
        if (startIndex < 0) {
            startIndex = 0;
        }
        if ( this.paths.size == 0) {
            return array;
        }
        if (this.paths.has(layer) === false) {
            return array;
        }

        let path = this.paths.get(layer);
        let count = path.unpack(array, startIndex);
        return count;
    }
    pckagedLength(): number {
        return Cartesian3.packedLength;
    }
    lineIndice(layer: number): UNION_NUMBER_ARRAY {
        throw new Error("Method not implemented.");
    }
    pushBack(layer: number, newPoint: ICartesian): number {
        Check.defined('newPoint', newPoint);
        if (this.paths.has(layer) === false) {
           this.paths.set(layer, new PointsCollection()); 
        }
        let path = this.paths.get(layer);
        path.push(newPoint);
        return path.length;
    }

    pushBackPS(layer: number, newPoints: UNION_NUMBER_ARRAY ): number {
        Check.defined('newPoints', newPoints);
        if (this.paths.has(layer) === false) {
           this.paths.set(layer, new PointsCollection()); 
        }
        let path = this.paths.get(layer);        
        path.unpack(newPoints, 0);
        return path.length;
    }

    equals(other: HGeometry): boolean {
        if ( !defined(other)) {
            return false; 
        }
        if (!(other instanceof HPolyline)) {
            return false; 
        }
        if (this.paths.size != other.paths.size) {
            return false; 
        }
        for (let key of this.paths.keys()) {
            const path = this.paths.get(key);
            let _same = false;
            for(let key2 of other.paths.keys()) {
                const path2 = other.paths.get(key2);
                if(path.equals(path2)){
                    _same = true;
                    break;
                } 
            }
            if (_same === false) {
                return false; 
            }
        }
        return true;
    }
    update(): boolean {
        throw new Error("Method not implemented.");
    }
    
}